package com.wpzf.zxhc.utils;

import com.aspose.words.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.xwpf.usermodel.LineSpacingRule;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class NpoiHelper {
    /**
     * 添加段落
     *
     * @param document
     * @param text
     * @param option
     * @return
     */
    public static XWPFParagraph newParagraph(XWPFDocument document, String text, Option option) {
        if (option == null)
            option = new Option();
        List<String> list = new ArrayList<String>() {
            {
                add(text);
            }
        };
        return newParagraph(document, list, option);
    }

    /// <summary>
    /// 添加段落
    /// </summary>
    /// <param name="document"></param>
    /// <param name="texts">多行文本</param>
    /// <param name="option">参数</param>
    /// <returns></returns>
    public static XWPFParagraph newParagraph(XWPFDocument document, List<String> texts, Option option) {
        if (option == null)
            option = new Option();

        XWPFParagraph paragraph = document.createParagraph();//创建段落对象
        paragraph.setAlignment(option.getAlign());//文字显示位置,段落排列（左对齐，居中，右对齐）
        paragraph.setSpacingBetween(option.getRowSpacing(), LineSpacingRule.AUTO);
        //if (texts[0].StartsWith("\t"))
        //{
        //    paragraph.IndentationFirstLine = 400;
        //}

        for (int i = 0; i < texts.size(); i++) {
            XWPFRun xwpfRun = paragraph.createRun();//创建段落文本对象
            xwpfRun.setBold(option.isBold);//文字加粗
            xwpfRun.setText(texts.get(i));//填充内容
            xwpfRun.setFontSize(option.getFontSize());//设置文字大小
            xwpfRun.setItalic(option.isItalic());//是否设置斜体（字体倾斜）
            xwpfRun.setColor(option.getFontColor());//设置字体颜色--十六进制
            xwpfRun.setFontFamily(option.getFontFamily(), XWPFRun.FontCharRange.eastAsia); //设置标题样式如：（微软雅黑，隶书，楷体）根据自己的需求而定
            if (i < texts.size() - 1)
                xwpfRun.addCarriageReturn();
        }
        return paragraph;
    }

    /**
     * 设置表格字体样式
     *
     * @param table
     * @param text
     * @param option
     * @return
     */
    public static XWPFParagraph setCellText(XWPFTable table, String text, Option option) {
        if (option == null)
            option = new Option();

        //table中的文字格式设置
        XWPFParagraph pCell = new XWPFParagraph(CTP.Factory.newInstance(), table.getBody());
        pCell.setWordWrapped(true);
        pCell.setAlignment(option.getAlign()); //字体居中
        pCell.setVerticalAlignment(TextAlignment.CENTER);//字体居中
        //pCell.setSpacingBetween(option.RowSpacing, LineSpacingRule.AUTO);

        XWPFRun xwpfRun = pCell.createRun();//创建段落文本对象
        xwpfRun.setBold(option.isBold());//文字加粗
        xwpfRun.setText(text);//填充内容
        xwpfRun.setFontSize(option.getFontSize());//设置文字大小
        xwpfRun.setItalic(option.isItalic());//是否设置斜体（字体倾斜）
        xwpfRun.setColor(option.getFontColor());//设置字体颜色--十六进制
        xwpfRun.setFontFamily(option.getFontFamily(), XWPFRun.FontCharRange.ascii); //设置标题样式如：（微软雅黑，隶书，楷体）根据自己的需求而定


        return pCell;
    }

    /**
     * 通用表格
     *
     * @param document
     * @param tableTitle
     * @param datas
     * @param title
     * @param pos
     * @return
     */
    public static XWPFTable setComTable(XWPFDocument document, List<TableTitle> tableTitle
            , List<Map<String, Object>> datas, String title, int pos) {
        //标题
//        if (!StringUtils.isEmpty(title) && pos > -1) {
//            Option option = new Option();
//            option.setAlign(ParagraphAlignment.CENTER);
//            option.setRowSpacing(1);
//            document.setParagraph(newParagraph(document, title, option), pos);
//        }
        //表格
        XWPFTable table = document.createTable(1, tableTitle.size());
        table.setWidth(tableTitle.stream().mapToInt(TableTitle::getWidth).sum());
        //表头
        for (int i = 0; i < tableTitle.size(); i++) {

            XWPFTableCell cell = table.getRow(0).getCell(i);

            CTTcPr ctTcPr = cell.getCTTc().isSetTcPr() ? cell.getCTTc().getTcPr() : cell.getCTTc().addNewTcPr();
            CTTblWidth ctTblWidth = ctTcPr.addNewTcW();
            int width = tableTitle.get(i).getWidth();
            ctTblWidth.setW(BigInteger.valueOf(width));
            ctTblWidth.setType(STTblWidth.DXA);

            cell.setColor("DBE5F1");
            Option option = new Option();
            option.setBold(true);
            option.setAlign(ParagraphAlignment.CENTER);
            XWPFParagraph paragraph = setCellText(table, tableTitle.get(i).getName(), option);
            cell.setParagraph(paragraph);
        }

        //内容
        for (int row = 0; row < datas.size(); row++) {
            XWPFTableRow mr = table.createRow();
            for (int col = 0; col < tableTitle.size(); col++) {
                TableTitle cobj = tableTitle.get(col);
                XWPFTableCell cell = mr.getCell(col);
                Object o = datas.get(row).get(cobj.key);
                String text = o == null ? "" : o.toString();
                if (cobj.xsw > -1) {
                    BigDecimal bd = new BigDecimal(Double.parseDouble(text));
                    Double f1 = bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                    text = f1.toString();
                }
                Option option = new Option();
                option.setAlign(cobj.align);
                XWPFParagraph paragraph = setCellText(table, text, option);
                cell.setParagraph(paragraph);
            }
        }
        return table;
    }

    /**
     * 跨列合并
     *
     * @param table
     * @param row
     * @param fromCell
     * @param toCell
     */
    public static void mergeHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if (cellIndex == fromCell) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 跨行合并
     *
     * @param table
     * @param col
     * @param fromRow
     * @param toRow
     */
    public void mergeVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if (rowIndex == fromRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
        //合并后垂直居中
        table.getRow(fromRow).getCell(col).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    }

    /**
     * 跨行合并
     *
     * @param table
     * @param col
     * @param fromRow
     * @param toRow
     */
    public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            CTTc cttc = cell.getCTTc();
            if (cttc.getTcPr() == null) {
                cttc.addNewTcPr();
            }
            //第一个合并单元格用重启合并值设置
            if (rowIndex == fromRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                //合并第一个单元格的单元被设置为“继续”
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 标题
     *
     * @param document
     * @param title
     * @param pos
     */

    public static void title(XWPFDocument document, String title, int pos) {
        List list = new ArrayList<String>() {
            {
                add("");
                add(title);
            }
        };
        Option option = new Option();
        option.setFontSize(19);
        option.setAlign(ParagraphAlignment.CENTER);
        option.setBold(true);
        document.setParagraph(newParagraph(document, list, option), pos);
    }

    /**
     * 目录
     *
     * @param document
     * @param text
     * @param pos
     */
    public static void catalog(XWPFDocument document, String text, int pos) {
        Option option = new Option();
        option.setFontSize(14);
        option.setBold(true);
        document.setParagraph(newParagraph(document, text, option), pos);
    }

    /**
     * 内容
     *
     * @param document
     * @param count
     * @param pos
     */
    public static void content(XWPFDocument document, String count, int pos) {
        document.setParagraph(newParagraph(document, count, null), pos);
    }

    /**
     * 内容
     *
     * @param document
     * @param contents
     * @param pos
     */
    public static void content(XWPFDocument document, List<String> contents, int pos) {
        document.setParagraph(newParagraph(document, contents, null), pos);
    }

    // 选项类
    public static class Option {
        public Option() {
            setAlign(ParagraphAlignment.LEFT);
            setBold(false);
            setFontColor("000000");
            setFontFamily("宋体");
            setRowSpacing(1.5);
            setFontSize(12);
        }

        // 水平对齐
        private ParagraphAlignment align;
        // 文字加粗
        private boolean isBold;
        // 文字斜体
        private boolean isItalic;
        // 字体大小（默认小四 12）
        private int fontSize;
        // 字体（宋体，微软雅黑，隶书，楷体）
        private String fontFamily;
        // 字体颜色（十六进制）
        private String fontColor;
        // 行间距（默认1.5）
        private double rowSpacing;

        public ParagraphAlignment getAlign() {
            return align;
        }

        public void setAlign(ParagraphAlignment align) {
            this.align = align;
        }

        public boolean isBold() {
            return isBold;
        }

        public void setBold(boolean bold) {
            isBold = bold;
        }

        public boolean isItalic() {
            return isItalic;
        }

        public void setItalic(boolean italic) {
            isItalic = italic;
        }

        public int getFontSize() {
            return fontSize;
        }

        public void setFontSize(int fontSize) {
            this.fontSize = fontSize;
        }

        public String getFontFamily() {
            return fontFamily;
        }

        public void setFontFamily(String fontFamily) {
            this.fontFamily = fontFamily;
        }

        public String getFontColor() {
            return fontColor;
        }

        public void setFontColor(String fontColor) {
            this.fontColor = fontColor;
        }

        public double getRowSpacing() {
            return rowSpacing;
        }

        public void setRowSpacing(double rowSpacing) {
            this.rowSpacing = rowSpacing;
        }
    }

    // 表格头
    public static class TableTitle {
        public TableTitle() {
            setAlign(ParagraphAlignment.LEFT);
            setWidth(1000);
            setXsw(-1);
        }

        ;
        // 主键
        private String key;
        // 名称
        private String name;
        /// 水平对齐
        private ParagraphAlignment align;
        /// 宽
        private int width;
        /// 小数位(-1表示不计算，通常为汉字)
        private int xsw;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public ParagraphAlignment getAlign() {
            return align;
        }

        public void setAlign(ParagraphAlignment align) {
            this.align = align;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getXsw() {
            return xsw;
        }

        public void setXsw(int xsw) {
            this.xsw = xsw;
        }
    }

    public static boolean getLicense() {
        boolean result = false;
        InputStream is = null;
        try {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                    "<License>\n" +
                    "    <Data>\n" +
                    "        <Products>\n" +
                    "            <Product>Aspose.Total for Java</Product>\n" +
                    "            <Product>Aspose.Words for Java</Product>\n" +
                    "        </Products>\n" +
                    "        <EditionType>Enterprise</EditionType>\n" +
                    "        <SubscriptionExpiry>20991231</SubscriptionExpiry>\n" +
                    "        <LicenseExpiry>20991231</LicenseExpiry>\n" +
                    "        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>\n" +
                    "    </Data>\n" +
                    "    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>\n" +
                    "</License>\n";
            is = new ByteArrayInputStream(xml.getBytes());
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static boolean doc2pdf(String inPath, String outPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return false;
        }
        FileOutputStream os = null;
        try {
            //取用户字体目录
            String userfontsfoloder = System.getProperty("user.home") + "\\Microsoft\\Windows\\Fonts\\";
            System.out.println("userfontsfoloder:" + userfontsfoloder);
            FontSourceBase[] fontSourceBases = FontSettings.getDefaultInstance().getFontsSources();
            FontSourceBase[] updatedFontSources = new FontSourceBase[FontSettings.getDefaultInstance().getFontsSources().length + 1];

            //将用户目录字体添加到字体源中
            FolderFontSource folderFontSource = new FolderFontSource(userfontsfoloder, true);

            for (int i = 0; i < fontSourceBases.length; i++) {
                updatedFontSources[i] = fontSourceBases[i];
            }
            updatedFontSources[fontSourceBases.length] = folderFontSource;

            FontSettings.getDefaultInstance().setFontsSources(updatedFontSources);

            long old = System.currentTimeMillis();
            File file = new File(outPath); // 新建一个空白pdf文档
            os = new FileOutputStream(file);
            com.aspose.words.Document doc = new com.aspose.words.Document(inPath); // Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            System.out.println("pdf转换成功，共耗时：" + ((now - old) / 1000.0) + "秒"); // 转化用时
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
}
